﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using METU_CMT.DataSets.METUCMTDataSetTableAdapters;

namespace METU_CMT.Business
{
    public enum UserType
    {
        Instructor, TA, Student, Admin, NA
    }

    public class EntityFactory
    {
        private int courseId;

        private static User user;

        public static User User
        {
            get
            {
                return (User)HttpContext.Current.Session["User"];
            }
            set { HttpContext.Current.Session["User"] = value; }
        }

        public static int CourseId
        {
            get
            {
                return int.Parse(HttpContext.Current.Session["CourseId"].ToString());
            }
            set { HttpContext.Current.Session["CourseId"] = value; }
        }

        private static CourseInstructor CourseInstanceInstructor
        {
            get
            {
                return (CourseInstructor)HttpContext.Current.Session["CourseInstanceInstructor"];
            }
            set { HttpContext.Current.Session["CourseInstanceInstructor"] = value; }
        }

        private static CourseTA CourseInstanceTeachingAssistant
        {
            get { return (CourseTA)HttpContext.Current.Session["CourseInstanceTeachingAssistant"]; }
            set { HttpContext.Current.Session["CourseInstanceTeachingAssistant"] = value; }
        }

        private static Course CourseInstanceStudent
        {
            get { return (Course)HttpContext.Current.Session["CourseInstanceStudent"]; }
            set { HttpContext.Current.Session["CourseInstanceStudent"] = value; }
        }

        public static List<Student> GetAllStudents()
        {
            UsersTableAdapter _usersTableAdapter = new UsersTableAdapter();
            return _usersTableAdapter.GetAllStudents();
        }

        public static List<User> GetAllUsers()
        {
            UsersTableAdapter _usersTableAdapter = new UsersTableAdapter();
            return _usersTableAdapter.GetAll();
        }

        public static List<Instructor> GetAllInstructors()
        {
            UsersTableAdapter _usersTableAdapter = new UsersTableAdapter();
            return _usersTableAdapter.GetAllInstructors();
        }

        public static List<Instructor> GetInstructorsOfCourse()
        {
            CourseInstructor _courseInstructor = new CourseInstructor(CourseId);
            return _courseInstructor.Instructors;
        }

        public static List<TeachingAssistant> GetTeachingAssistantsOfCourse(int courseId)
        {
            CourseInstructor _courseInstructor = new CourseInstructor(courseId);
            return _courseInstructor.TAs;
        }

        public static List<Student> GetStudentsOfCourse(int courseId)
        {
            return new CourseInstructor(courseId).Students;
        }


        public static List<Course> GetCourseOfInstructor(int userId)
        {
            List<Course> _allCourses = GetAllCourses();
            return _allCourses.Where(
                course => course.Instructors.Any(instructor => instructor.UserId == userId))
                .ToList();
        }

        public static List<Course> GetCourseOfStudent(int userId)
        {
            List<Course> _allCourses = GetAllCourses();
            return _allCourses.Where(
                course => course.Students.Any(student => student.UserId == userId))
                .ToList();
        }

        public static List<Course> GetCourseOfTeachingAssistant(int userId)
        {
            List<Course> _allCourses = GetAllCourses();
            return _allCourses.Where(
                course => course.TAs.Any(teachingAssistant => teachingAssistant.UserId == userId))
                .ToList();
        }

        private static List<Course> GetAllCourses()
        {
            CourseTableAdapter _courseTableAdapter = new CourseTableAdapter();
            return _courseTableAdapter.GetAllCourses();
        }

        public static User GetUser(string userName, string password)
        {
            UserType _role = GetUserType(userName, password);

            if (User == null)
            {
                UsersTableAdapter _usersTableAdapter = new UsersTableAdapter();
                int _userId = _usersTableAdapter.GetUserId(userName);

                switch (_role)
                {
                    case UserType.Instructor:
                        user = new Instructor(userName);
                        break;
                    case UserType.Student:
                        user = new Student(_userId);
                        if (((Student)user).ExpiryDate.CompareTo(DateTime.Now) < 0)
                        {
                            return null;
                        }
                        break;
                    case UserType.TA:
                        user = new TeachingAssistant(_userId);
                        break;
                    case UserType.Admin:
                        user = new Administrator(_userId);
                        break;
                    case UserType.NA:
                        user = null;
                        break;
                }

                User = user;
            }

            return User;
        }

        private static UserType GetUserType(string userName, string password)
        {
            return new UsersTableAdapter().GetUserType(userName, password);
        }

        public static List<string> GetUserRoles()
        {
            return new List<string> { "Instructor", "Teaching Assistant", "Student" };
        }

        public static Course GetCurrentCourse(UserType userType)
        {
            switch (userType)
            {
                case UserType.Instructor:
                    CourseInstanceInstructor = new CourseInstructor(CourseId);
                    return CourseInstanceInstructor;
                case UserType.Student:
                    CourseInstanceStudent = new Course(CourseId);
                    return CourseInstanceStudent;
                case UserType.TA:
                    CourseInstanceTeachingAssistant = new CourseTA(CourseId);
                    return CourseInstanceTeachingAssistant;
            }
            return null;
        }

        public static List<TeachingAssistant> GetAllTeachingAssistants()
        {
            //TODO: Not Implemented
            UsersTableAdapter _usersTableAdapter = new UsersTableAdapter();
            return _usersTableAdapter.GetTeachingAssistants();
        }

        public static List<Event> GetAllEvents()
        {
            EventTableAdapter _eventTableAdapter = new EventTableAdapter();
            return _eventTableAdapter.GetAllEvents();
        }

        public static void RecoverPassword(string email, TextBox txtUsername)
        {
            UsersTableAdapter _usersTableAdapter = new UsersTableAdapter();
            _usersTableAdapter.RecoverPassword(email, txtUsername.Text);
        }

        public static void Permit()
        {
            Permitter _permitter = new Permitter();
            if (User == null)
            {
                HttpContext.Current.Response.Redirect("~/NotAuthorized.htm");
            }
            else
            {
                bool _isUserPermitted = _permitter.IsUserPermitted(User.UserName, HttpContext.Current.Request.Url.ToString());
                if (_isUserPermitted == false)
                {
                    HttpContext.Current.Response.Redirect("~/NotAuthorized.htm");
                }
            }
        }
    }
}
